package com.oms.core.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import com.ibatis.sqlmap.client.SqlMapExecutor;
import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
import com.ibatis.sqlmap.engine.mapping.sql.stat.StaticSql;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.oms.core.dao.IGeneralDAO;

/**
 * IGeneralDAO的实现
 * @author Loong_Mit
 * @date Sep 1, 2012 5:29:08 PM
 */

public class GeneralDAO<E, PK extends Serializable> extends SqlMapClientDaoSupport implements
		IGeneralDAO<E, PK> {
	
	/** XXXMapper.xml对应节点ID **/
	public static final String SQLID_INSERT = "insert";

	public static final String SQLID_UPDATE = "update";

	public static final String SQLID_DELETE = "delete";

	public static final String SQLID_SELECT = "select";

	public static final String SQLID_GETALL = "getAll";

	public static final String SQLID_SELECT_BY_PK = "selectByPK";

	public static final String SQLID_COUNT = "count";
	
	protected String sqlmapNamespace = "";
	
	@Override
	public void batchDelete(final List<PK> list) {
		SqlMapClientCallback callback = new SqlMapClientCallback() {
			public Object doInSqlMapClient(SqlMapExecutor executor)
					throws SQLException {
				executor.startBatch();
				for (PK member : list) {
					executor.delete(sqlmapNamespace + SQLID_DELETE, member);
				}
				executor.executeBatch();
				return null;
			}
		};

		this.getSqlMapClientTemplate().execute(callback);
	}

	@Override
	public void batchInsert(final List<E> list) {
		SqlMapClientCallback callback = new SqlMapClientCallback() {
			public Object doInSqlMapClient(SqlMapExecutor executor)
					throws SQLException {
				executor.startBatch();
				for (E member : list) {
					executor.insert(sqlmapNamespace + SQLID_INSERT, member);
				}
				executor.executeBatch();
				return null;
			}
		};

		this.getSqlMapClientTemplate().execute(callback);
	}

	@Override
	public void batchUpdate(final List<E> list) {
		SqlMapClientCallback callback = new SqlMapClientCallback() {
			public Object doInSqlMapClient(SqlMapExecutor executor)
					throws SQLException {
				executor.startBatch();
				for (E member : list) {
					executor.update(sqlmapNamespace + SQLID_UPDATE, member);
				}
				executor.executeBatch();
				return null;
			}
		};

		this.getSqlMapClientTemplate().execute(callback);
	}

	@Override
	public int count() {
		return ((Integer) getSqlMapClientTemplate().queryForObject(sqlmapNamespace + SQLID_COUNT)).intValue();
	}
	
	@Override
	public int getCount(String sqlId, Object parameters) {
		return ((Integer) getSqlMapClientTemplate().queryForObject(sqlmapNamespace + sqlId, parameters)).intValue();
	}

	@Override
	public int delete(Serializable primaryKey) {
		return this.getSqlMapClientTemplate().delete(sqlmapNamespace + SQLID_DELETE, primaryKey);
	}

	@Override
	public void delete(String sqlId, Object parameters) {
		this.getSqlMapClientTemplate().delete(sqlmapNamespace + sqlId, parameters);
	}

	@Override
	public E get(Serializable primaryKey) {
		return (E) this.getSqlMapClientTemplate().queryForObject(sqlmapNamespace + SQLID_SELECT_BY_PK, primaryKey);
	}

	@Override
	public List<E> getAll() {
		return getAll(null);
	}

	@Override
	public List<E> getAll(Map<String, Object> params) {
		return (List<E>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + SQLID_GETALL, params);
	}

	@Override
	public void insert(Object entity) {
		this.getSqlMapClientTemplate().insert(sqlmapNamespace + SQLID_INSERT, entity);
	}
	@Override
	public void insert(String sqlId, Object entity) {
		this.getSqlMapClientTemplate().insert(sqlmapNamespace + sqlId, entity);
	}

	@Override
	public List<E> queryForList(String sqlId) {
		return (List<E>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + sqlId);
	}

	@Override
	public List<E> queryForList(String sqlId, Object parameters) {
		return (List<E>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + sqlId, parameters);
	}

	@Override
	public List<E> queryForList(String sqlId, String sql) {
		return (List<E>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + sqlId, ((StringUtils.isEmpty(sql)) ? null : sql));
	}

	@Override
	public List<E> queryForList(String sqlId, Map<String, Object> map) {
		return (List<E>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + sqlId, map);
	}

	@Override
	public E queryForObject(String sqlId, Object parameters) {
		return (E) getSqlMapClientTemplate().queryForObject(sqlmapNamespace + sqlId, parameters);
	}

	@Override
	public int update(Object entity) {
		return this.getSqlMapClientTemplate().update(sqlmapNamespace + SQLID_UPDATE, entity);
	}

	@Override
	public void update(String sqlId, Object parameters) {
		this.getSqlMapClientTemplate().update(sqlmapNamespace + sqlId, parameters);
	}
	
	@Override
	public List<Map<String, Object>> getList(String sqlId, Object parameters) {
		return (List<Map<String,Object>>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + sqlId, parameters);
	}
	
	@Override
	public List<Map<String, Object>> getList(String sqlId, Map<String, Object> map) {
		return (List<Map<String,Object>>) this.getSqlMapClientTemplate().queryForList(sqlmapNamespace + sqlId, map);
	}
	
	/**
	 * 执行某个sqlId的SQL
	 * @param sqlId
	 * @return
	 * Administrator
	 */
	protected String getExecuteSql(String sqlId) {
		SqlMapClientImpl sqlmap = (SqlMapClientImpl) this.getSqlMapClient();
		MappedStatement stmt = sqlmap.getMappedStatement(sqlmapNamespace + sqlId);
		StaticSql stmtSql = (StaticSql) stmt.getSql();
		String sql = stmtSql.getSql(null, null);

		return sql;
	}
	
	/**
	 * sqlmapNamespace，对应XXXMapper.xml中的命名空间
	 * @return
	 */
	public String getSqlmapNamespace() {
		return sqlmapNamespace.substring(0, sqlmapNamespace.length()-1);
	}

	/**
	 * sqlmapNamespace的设置方法，可用于spring注入
	 * @param sqlmapNamespace
	 */
	public void setSqlmapNamespace(String sqlmapNamespace) {
		this.sqlmapNamespace = sqlmapNamespace + ".";
	}
}
